package com.apes.fn.business.fixedLoss.service;

import afu.org.checkerframework.checker.units.qual.A;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.business.carAccident.modle.CarAccident;
import com.apes.fn.business.carAccident.repository.CarAccidentRepository;
import com.apes.fn.business.fixedLoss.modle.LossQuotation;
import com.apes.fn.business.fixedLoss.modle.LossQuotationPlan;
import com.apes.fn.business.fixedLoss.modle.LossQuotationReport;
import com.apes.fn.business.fixedLoss.modle.LossQuotationReportItem;
import com.apes.fn.business.fixedLoss.repository.LossQuotationReportItemRepository;
import com.apes.fn.business.fixedLoss.repository.LossQuotationReportRepository;
import com.apes.fn.business.fixedLoss.repository.LossQuotationRepository;
import com.apes.fn.scm.retailOrder.model.RetailOrder;
import com.apes.fn.scm.retailOrder.repository.RetailOrderRepository;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.soe.metadata.Scene;
import com.apes.framework.util.DateUtil;
import com.apes.scm.masterdata.party.model.PartyRole;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program:
 * @description: 定损报表
 * @author: lws
 * @create: 2022/10/14 17:30
 **/
@Service("lossQuotationReportService")
public class LossQuotationReportService {

    @Autowired
    private RetailOrderRepository retailOrderRepository;

    @Autowired
    private LossQuotationRepository lossQuotationRepository;

    @Autowired
    private CarAccidentRepository carAccidentRepository;

    @Autowired
    private LossQuotationReportItemRepository lossQuotationReportItemRepository;

    @Autowired
    private LossQuotationReportRepository lossQuotationReportRepository;

    /**
     * 定损跟踪报表
     */
    public String lossTraceReport(SimpleRequest request){
        Date date = new Date();
        Date startTemp = DateUtil.parse(DateUtil.format(date, DateUtil.SHOW_DATE_FORMAT), DateUtil.SHOW_DATE_FORMAT);
        Date start = DateUtil.parse(DateUtil.timeStampToStr(startTemp.getTime()-86400000L), DateUtil.SHOW_DATE_FORMAT);
        Date end = DateUtil.parse(DateUtil.timeStampToStr(startTemp.getTime()), DateUtil.SHOW_DATE_FORMAT);
        return lossTraceReportStatistics(start,end);
    }

    private String lossTraceReportStatistics(Date startDate,Date endDate){
        // 获取时间范围内的零售单
        List<Map> originData = retailOrderRepository.findLossQuotationReport(startDate, endDate);
        // 过滤
        List<Map> result = filterByLossTraceReport(originData);
        // 过滤车牌号码+报案号重复的
        List<Map> filterResult = filterByDistinct(result);
        // 统计
        return statisticsByLossTraceReport(filterResult);
    }

    private List<Map> filterByDistinct(List<Map> originData){
        List<Map> result = new ArrayList<>();
        originData.stream().forEach(dataItem -> {
            CarAccident carAccident = (CarAccident) dataItem.get("carAccident");
            for (int i = 0; i < result.size(); i++) {
                Map map = result.get(i);
                CarAccident carAccidentByResult = (CarAccident) map.get("carAccident");
                if (carAccidentByResult.getCarNumber() == carAccident.getCarNumber()
                    && carAccidentByResult.getReportNumber() == carAccident.getReportNumber()){
                    return;
                }
            }
            result.add(dataItem);
        });
        return result;
    }

    private List<Map> filterByLossTraceReport(List<Map> originData){
        return originData.stream().filter(dataItem ->{
            // 零售单的场景流为RO002，RO003,来源单据为定损
            RetailOrder retailOrder = (RetailOrder)dataItem.get("retailOrder");
            Scene scene = retailOrder.getScene();
            if(scene == null || !("RO002".equals(scene.getId()) || "RO003".equals(scene.getId()))) return false;
            // 根据零售单查询其定损单，再根据定损单查询车险报案单，再判断车险报案单的商务跟踪人不为空
            CarAccident carAccident = (CarAccident) dataItem.get("carAccident");
            if (carAccident.getBusinessStaff() == null) return false;
            // 车牌号码+报案号在报表中已经存在时数据不统计
            List<LossQuotationReportItem> lossQuotationReportItems = lossQuotationReportItemRepository.findByCarNumberAndReportNumber(carAccident.getCarNumber(), carAccident.getReportNumber());
            if (lossQuotationReportItems.size() > 0) return false;
            return true;
        }).collect(Collectors.toList());
    }

    public String statisticsByLossTraceReport(List<Map> result){
        List<LossQuotationReportItem> lossQuotationReportItems = new ArrayList<>();
        result.stream().forEach(item -> {
            RetailOrder retailOrder = (RetailOrder) item.get("retailOrder");
            LossQuotation lossQuotation = (LossQuotation) item.get("lossQuotation");
            CarAccident carAccident = (CarAccident) item.get("carAccident");
            // 封装定损跟踪报表数据
            LossQuotationReportItem lossQuotationReportItem = new LossQuotationReportItem();
            lossQuotationReportItem.setStatisticDate(formatDate(retailOrder.getCreateDate()));
            lossQuotationReportItem.setCarNumber(carAccident.getCarNumber());
            lossQuotationReportItem.setRetailOrderId(retailOrder.getId());
            lossQuotationReportItem.setLossQuotationId(lossQuotation.getId());
            lossQuotationReportItem.setCarAccidentId(carAccident.getId());
            lossQuotationReportItem.setReportNumber(carAccident.getReportNumber());
            lossQuotationReportItem.setCaseType(carAccident.getCaseType());
            lossQuotationReportItem.setBusinessStaff(carAccident.getBusinessStaff());
            lossQuotationReportItem.setFixedLossDept(lossQuotation.getFixedLossDept());
            lossQuotationReportItem.setGetCarDept(lossQuotation.getGetCarDept());
            lossQuotationReportItem.setInsuranceCompany(lossQuotation.getInsuranceCompany());
            lossQuotationReportItem.setOrderType(lossQuotation.getOrderType());
            lossQuotationReportItems.add(lossQuotationReportItem);
        });
        // 根据商务跟踪人与统计时间分组
        Map<String, List<LossQuotationReportItem>> groupData = lossQuotationReportItems.stream()
                .collect(Collectors.groupingBy(lossQuotationReportItem -> lossQuotationReportItem.getBusinessStaff().getId() +
                                                                          lossQuotationReportItem.getStatisticDate().toString()));
        // 一组为一个主表数据
        Collection<List<LossQuotationReportItem>> values = groupData.values();
        values.stream().forEach(item ->{
            LossQuotationReport lossQuotationReport = new LossQuotationReport();
            item.stream().forEach(item2 -> item2.setLossQuotationReport(lossQuotationReport));
            lossQuotationReport.setLossQuotationReportItems(item);
            lossQuotationReport.setStatisticDate(item.get(0).getStatisticDate());
            lossQuotationReport.setBusinessStaff(item.get(0).getBusinessStaff());
            lossQuotationReport.setCountTraceArrival(item.size());
            lossQuotationReport.setCountInsuranceMember(item.stream().filter(item2 -> "车险会员报案".equals(item2.getCaseType().getDescription())).count());
            lossQuotationReport.setCountNotInsuranceMember(item.stream().filter(item2 -> "非车险会员推送".equals(item2.getCaseType().getDescription())).count());
            lossQuotationReport.setCountRedBull(item.stream().filter(item2 -> "红牛案件到店".equals(item2.getCaseType().getDescription())).count());
            lossQuotationReport.setCountSurveyArrived(item.stream().filter(item2 -> "代勘到店".equals(item2.getCaseType().getDescription())).count());
            lossQuotationReport.setCountCollaborationInsurance(item.stream().filter(item2 -> "门店接车合作保险公司".equals(item2.getCaseType().getDescription())).count());
            lossQuotationReport.setCountNotCollaborationInsurance(item.stream().filter(item2 -> "门店接车非合作保险".equals(item2.getCaseType().getDescription())).count());
            lossQuotationReportRepository.save(lossQuotationReport);
            lossQuotationReportItemRepository.saveAll(item);
        });
        return "统计"+ values.size() +"条主数据，统计"+ lossQuotationReportItems.size() +"条明细数据";
    }

    /**
     * 将时间格式化为日期
     * @param date
     * @return
     */
    private Date formatDate(Date date){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date result = new Date();
        try {
            result = simpleDateFormat.parse(simpleDateFormat.format(date));
        } catch (ParseException e) {
            throw new RuntimeException("统计时间转化失败！");
        }
        return result;
    }

    /**
     * 定损跟踪报表（开发人员使用）
     * @param request  传入开始时间到结束时间
     * @return
     */
    public String lossTraceReportTest(SimpleRequest request){
        JSONObject requestJO = request.getJO();
        Date startDate = requestJO.getDate("startDate");
        Date endDate = requestJO.getDate("endDate");
        return lossTraceReportStatistics(startDate,endDate);
    }

}
